package com.ydl.partitionscheduler.service;

import com.ydl.partitionscheduler.builder.PartitionStatementBuilder;
import com.ydl.partitionscheduler.builder.PartitionStatementBuilderFactory;
import com.ydl.partitionscheduler.config.TablePartitionProperties;
import com.ydl.partitionscheduler.model.PartitionInfo;
import com.ydl.partitionscheduler.strategy.PartitionStrategyFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class PartitionService {

    private final JdbcTemplate jdbcTemplate;
    private final TablePartitionProperties partitionProperties;
    private final PartitionStrategyFactory strategyFactory;
    private final PartitionStatementBuilderFactory statementBuilderFactory;

    /**
     * 为所有配置的表创建预分区
     */
    public void createPrePartitions() {
        log.info("开始创建预分区...");

        List<TablePartitionProperties.TablePartitionConfig> tableConfigs = partitionProperties.getTables();
        if (tableConfigs == null || tableConfigs.isEmpty()) {
            log.warn("没有配置需要分区的表");
            return;
        }

        PartitionStatementBuilder statementBuilder = statementBuilderFactory.getBuilder();

        for (TablePartitionProperties.TablePartitionConfig config : tableConfigs) {
            try {
                log.info("处理表: {}", config.getMainTable());
                createPartitionsForTable(config, statementBuilder);
            } catch (Exception e) {
                log.error("处理表 {} 分区时发生错误", config.getMainTable(), e);
            }
        }

        log.info("预分区创建完成");
    }

    /**
     * 为指定表创建分区
     */
    private void createPartitionsForTable(TablePartitionProperties.TablePartitionConfig config,
                                          PartitionStatementBuilder statementBuilder) {
        // 获取对应的分区策略
        var strategy = strategyFactory.getStrategy(config.getStrategy());

        // 生成需要创建的分区信息
        List<PartitionInfo> partitionsToCreate = strategy.generatePartitions(config);

        // 为每个分区执行创建操作
        for (PartitionInfo partition : partitionsToCreate) {
            if (!isPartitionExists(config.getMainTable(), partition.getPartitionName(), statementBuilder)) {
                createPartition(config, partition, statementBuilder);
                log.info("已创建分区: {}", partition.getPartitionName());
            } else {
                log.info("分区 {} 已存在，跳过创建", partition.getPartitionName());
            }
        }
    }

    /**
     * 检查分区是否已存在
     */
    private boolean isPartitionExists(String mainTable, String partitionName, PartitionStatementBuilder statementBuilder) {
        String sql = statementBuilder.buildExistsStatement(mainTable, partitionName);
        Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
        return count != null && count > 0;
    }

    /**
     * 创建分区
     */
    private void createPartition(TablePartitionProperties.TablePartitionConfig config,
                                 PartitionInfo partition,
                                 PartitionStatementBuilder statementBuilder) {
        String sql = statementBuilder.buildCreateStatement(config, partition);

        log.debug("执行分区创建SQL: {}", sql);
        jdbcTemplate.execute(sql);
    }
}
